#include "preHeader.h"
#include "Session/GameSession.h"
#include "Session/GameSessionHandler.h"
#include "SQLHelper.h"

int GameSessionHandler::HandleLoadAllSocialFriend(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto LoadAllSocialFriend = [GSRPCAsyncTaskArgs]() {
		AutoFeedbackLarge(buffer, error)
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (!connPtr) {
			error = DBPErrorConnectMysqlFailed;
			return;
		}
		size_t n = 0;
		uint32 lastInstID[2]{};
		auto sqlFormat = CreateSQL4SelectEntity<social_friend>(
			"characterId>%u OR (characterId=%u AND friendId>%u) ORDER BY characterId,friendId");
mark:	auto rst = connPtr->FastQueryFormat(
			sqlFormat.c_str(), lastInstID[0], lastInstID[0], lastInstID[1]);
		if (!rst) {
			error = DBPErrorQueryMysqlFailed;
			return;
		}
		while (rst.NextRow()) {
			auto row = rst.Fetch();
			auto instInfo = LoadEntityFromMysqlRow<social_friend>(row);
			SaveToINetStream(instInfo, buffer);
			lastInstID[0] = instInfo.characterId;
			lastInstID[1] = instInfo.friendId;
			if (++n % 2500 == 0) {
				GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, false);
				buffer.Clear();
			}
		}
		if (connPtr->GetLastErrno() != 0) {
			goto mark;
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(LoadAllSocialFriend));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleLoadAllSocialIgnore(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto LoadAllSocialIgnore = [GSRPCAsyncTaskArgs]() {
		AutoFeedbackLarge(buffer, error)
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (!connPtr) {
			error = DBPErrorConnectMysqlFailed;
			return;
		}
		size_t n = 0;
		uint32 lastInstID[2]{};
		auto sqlFormat = CreateSQL4SelectEntity<social_ignore>(
			"characterId>%u OR (characterId=%u AND ignoreId>%u) ORDER BY characterId,ignoreId");
mark:	auto rst = connPtr->FastQueryFormat(
			sqlFormat.c_str(), lastInstID[0], lastInstID[0], lastInstID[1]);
		if (!rst) {
			error = DBPErrorQueryMysqlFailed;
			return;
		}
		while (rst.NextRow()) {
			auto row = rst.Fetch();
			auto instInfo = LoadEntityFromMysqlRow<social_ignore>(row);
			SaveToINetStream(instInfo, buffer);
			lastInstID[0] = instInfo.characterId;
			lastInstID[1] = instInfo.ignoreId;
			if (++n % 2500 == 0) {
				GameSession::Feedback(gsPtr, buffer, info.sn, RPCErrorNone, false);
				buffer.Clear();
			}
		}
		if (connPtr->GetLastErrno() != 0) {
			goto mark;
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(LoadAllSocialIgnore));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteAllSocialData(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteAllSocialData = [GSRPCAsyncTaskArgs]() {
		uint32 characterId;
		(*pckPtr) >> characterId;
		AutoFeedback(buffer, error)
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (!connPtr) {
			error = DBPErrorConnectMysqlFailed;
			return;
		}
		auto rst1 = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<social_friend>
			("characterId=%u OR friendId=%u").c_str(), characterId, characterId);
		auto rst2 = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<social_ignore>
			("characterId=%u OR ignoreId=%u").c_str(), characterId, characterId);
		if (!rst1.second || !rst2.second) {
			error = DBPErrorDeleteMysqlFailed;
			return;
		}
	};
	sDeferAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteAllSocialData));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleNewSocialFriend(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto NewSocialFriend = [GSRPCAsyncTaskArgs]() {
		social_friend instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		AutoFeedback(buffer, error)
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (!connPtr) {
			error = DBPErrorConnectMysqlFailed;
			return;
		}
		auto sqlStr = CreateSQL4InsertEntity(instInfo);
		auto rst = connPtr->Execute(sqlStr.c_str());
		if (!rst.second) {
			error = DBPErrorInsertMysqlFailed;
			return;
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(NewSocialFriend));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteSocialFriend(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteSocialFriend = [GSRPCAsyncTaskArgs]() {
		uint32 characterId, friendId;
		(*pckPtr) >> characterId >> friendId;
		AutoFeedback(buffer, error)
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (!connPtr) {
			error = DBPErrorConnectMysqlFailed;
			return;
		}
		auto rst = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<social_friend>
			("characterId=%u AND friendId=%u").c_str(), characterId, friendId);
		if (!rst.second) {
			error = DBPErrorDeleteMysqlFailed;
			return;
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteSocialFriend));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleNewSocialIgnore(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto NewSocialIgnore = [GSRPCAsyncTaskArgs]() {
		social_ignore instInfo;
		LoadFromINetStream(instInfo, *pckPtr);
		AutoFeedback(buffer, error)
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (!connPtr) {
			error = DBPErrorConnectMysqlFailed;
			return;
		}
		auto sqlStr = CreateSQL4InsertEntity(instInfo);
		auto rst = connPtr->Execute(sqlStr.c_str());
		if (!rst.second) {
			error = DBPErrorInsertMysqlFailed;
			return;
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(NewSocialIgnore));
	return SessionHandleCapture;
}

int GameSessionHandler::HandleDeleteSocialIgnore(GameSession *pSession, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	auto DeleteSocialIgnore = [GSRPCAsyncTaskArgs]() {
		uint32 characterId, ignoreId;
		(*pckPtr) >> characterId >> ignoreId;
		AutoFeedback(buffer, error)
		auto connPtr = sMysqlDatabasePool.GetCharDB()->GetConnAutoPtr();
		if (!connPtr) {
			error = DBPErrorConnectMysqlFailed;
			return;
		}
		auto rst = connPtr->ExecuteFormat(CreateSQL4DeleteEntity<social_ignore>
			("characterId=%u AND ignoreId=%u").c_str(), characterId, ignoreId);
		if (!rst.second) {
			error = DBPErrorDeleteMysqlFailed;
			return;
		}
	};
	sAsyncTaskMgr.AddTask(CreateAsyncTask(DeleteSocialIgnore));
	return SessionHandleCapture;
}
